package com.jghz.transfer.service.impl;

import java.io.StringWriter;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;
import javax.xml.transform.stream.StreamResult;

import org.hibernate.annotations.common.util.StringHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.oxm.Marshaller;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.bstek.dorado.data.entity.EntityState;
import com.bstek.dorado.data.entity.EntityUtils;
import com.bstek.dorado.data.provider.Page;
import com.jghz.framework.exception.AppException;
import com.jghz.framework.utils.AppUtils;
import com.jghz.framework.utils.SpringHolder;
import com.jghz.transfer.constant.ActionType;
import com.jghz.transfer.dao.WayBillDao;
import com.jghz.transfer.entity.Logink;
import com.jghz.transfer.entity.Tbplateform;
import com.jghz.transfer.entity.waybill.ObjectFactory;
import com.jghz.transfer.entity.waybill.Root;
import com.jghz.transfer.entity.waybill.Root.Body;
import com.jghz.transfer.entity.waybill.Root.Body.ConsigneeInfo;
import com.jghz.transfer.entity.waybill.Root.Body.ConsignorInfo;
import com.jghz.transfer.entity.waybill.Root.Body.PriceInfo;
import com.jghz.transfer.entity.waybill.Root.Body.VehicleInfo;
import com.jghz.transfer.entity.waybill.Root.Body.VehicleInfo.Driver;
import com.jghz.transfer.entity.waybill.Root.Body.VehicleInfo.GoodsInfo;
import com.jghz.transfer.entity.waybill.Root.Header;
import com.jghz.transfer.service.LoginkService;
import com.jghz.transfer.service.WayBillService;

@Service
public class WayBillServiceImpl implements WayBillService {

	@Resource
	private WayBillDao wayBillDao;
	@Autowired
	private Marshaller marshaller;

	@Override
	public void load(Page<Tbplateform> page, Map<String, Object> paramater) throws Exception {

		if (paramater == null) {
			paramater = new HashMap<String, Object>();
		}
		if (!"admin".equals(AppUtils.getLoginUserName())) {
			paramater.put("senderCode", AppUtils.getLoginUserName());
		} else {
			paramater.put("senderCode", ((Logink) SpringHolder.getBean("logink")).getUsername());
		}
		wayBillDao.pagingQuery(page, paramater);
	}

	@Override
	@Transactional
	public void save(Collection<Tbplateform> cols) {
		for (Tbplateform plateform : cols) {
			EntityState state = EntityUtils.getState(plateform);
			if (state.equals(EntityState.DELETED)) {
				if (StringHelper.isNotEmpty(plateform.getStatus()) && "Y".equals(plateform.getStatus()))
					throw new RuntimeException("运单号" + plateform.getShippingNoteNumber() + "不是新建状态，不能删除");
				wayBillDao.delete(plateform);
			}
		}
	}

	@Override
	@Transactional
	public void send(Collection<Tbplateform> cols) throws Exception {
		if (cols == null || cols.size() == 0) {
			Map<String, Object> inMap = new HashMap<String, Object>();
			inMap.put("status", "N");
			cols = wayBillDao.queryList(inMap);
		}
		for (Tbplateform shMap : cols) {
			if (StringHelper.isEmpty(shMap.getStatus()) || "N".equals(shMap.getStatus())) {

				if (StringHelper.isNotEmpty(shMap.getDespatchActualDateTime())
						&& StringHelper.isNotEmpty(shMap.getGoodsReceiptDateTime())) {
					if (shMap.getDespatchActualDateTime().compareTo(shMap.getGoodsReceiptDateTime()) >= 0)
						throw new AppException("运单" + shMap.getShippingNoteNumber() + "签收时间"
								+ shMap.getDespatchActualDateTime() + "要晚于发车时间" + shMap.getGoodsReceiptDateTime());
				}
				Root root = assembleRoot(shMap);

				StringWriter sw = new StringWriter();
				marshaller.marshal(root, new StreamResult(sw));
				String xml = sw.toString();

				boolean result = LoginkService.sendXml(ActionType.LOGINK_CN_FREIGHTBROKER_WAYBILL.toString(), xml);
				shMap.setSendEmp(AppUtils.getLoginUserName());
				shMap.setSendTime(AppUtils.getCurrentDateString("yyyyMMdd HH:mm:ss"));
				if (result == true) {
					shMap.setStatus("Y");
				}
				wayBillDao.update(shMap);
			}
		}
	}

	private Root assembleRoot(Tbplateform tf) {
		Logink logink = SpringHolder.getBean("logink");
		ObjectFactory of = new ObjectFactory();

		/** ============== ConsignorInfo ============== **/
		ConsignorInfo consignorInfo = of.createRootBodyConsignorInfo();
		consignorInfo.setConsignor(tf.getConsignor());
		consignorInfo.setPersonalIdentityDocument(tf.getPersonalIdentityDocument());
		consignorInfo.setPlaceOfLoading(tf.getPlaceOfLoading());
		consignorInfo.setCountrySubdivisionCode(tf.getCountrySubdivisionCode());
		/** ============== ConsigneeInfo ============== **/
		ConsigneeInfo consigneeInfo = of.createRootBodyConsigneeInfo();
		consigneeInfo.setConsignee(tf.getConsignee());
		consigneeInfo.setGoodsReceiptPlace(tf.getGoodsReceiptPlace());
		consigneeInfo.setCountrySubdivisionCode(tf.getCountrySubdivisionCode2());
		/** ============== PriceInfo ============== **/
		PriceInfo priceInfo = of.createRootBodyPriceInfo();
		priceInfo.setTotalMonetaryAmount(
				AppUtils.getBigDecimal(tf.getTotalMonetaryAmount()).setScale(3, RoundingMode.HALF_UP));
		priceInfo.setRemark(tf.getRemark());
		/** ============== VehicleInfo ============== **/
		VehicleInfo vehicleInfo = of.createRootBodyVehicleInfo();
		// ** Driver **//
		Driver driver = of.createRootBodyVehicleInfoDriver();
		driver.setNameOfPerson(tf.getNameOfPerson());
		driver.setQualificationCertificateNumber(tf.getQualificationCertificateNumber());
		driver.setTelephoneNumber(tf.getTelephoneNumber());
		// ** GoodsInfo **//
		GoodsInfo goodsInfo = of.createRootBodyVehicleInfoGoodsInfo();
		goodsInfo.setDescriptionOfGoods(tf.getDescriptionOfGoods());
		goodsInfo.setCargoTypeClassificationCode(tf.getCargoTypeClassificationCode());
		BigDecimal goodsItemGrossWeight = AppUtils.getBigDecimal(tf.getGoodsItemGrossWeight())
				.multiply(new BigDecimal(1000)).setScale(2, RoundingMode.HALF_UP);
		goodsInfo.setGoodsItemGrossWeight(goodsItemGrossWeight);
		goodsInfo.setCube(AppUtils.getBigDecimal(tf.getCube().setScale(4, RoundingMode.HALF_UP)));
		goodsInfo.setTotalNumberOfPackages(tf.getTotalNumberOfPackages());

		// 填装VehicleInfo
		String licensePlateTypeCode = "01";
		if (StringHelper.isNotEmpty(tf.getLicensePlateTypeCode())) {
			licensePlateTypeCode = tf.getLicensePlateTypeCode();
		}
		vehicleInfo.setLicensePlateTypeCode(licensePlateTypeCode);
		vehicleInfo.setVehicleNumber(tf.getVehicleNumber());
		String vehicleClassificationCode = "H01";
		if (StringHelper.isNotEmpty(tf.getVehicleClassificationCode())) {
			vehicleClassificationCode = tf.getVehicleClassificationCode();
		}
		vehicleInfo.setVehicleClassificationCode(vehicleClassificationCode);
		vehicleInfo.setVehicleTonnage(AppUtils.getBigDecimal(tf.getVehicleTonnage().setScale(2, RoundingMode.HALF_UP)));
		String roadTransportCertificateNumber = "330111003790";
		if (StringHelper.isNotEmpty(tf.getRoadTransportCertificateNumber())) {
			roadTransportCertificateNumber = tf.getRoadTransportCertificateNumber();
		}
		vehicleInfo.setRoadTransportCertificateNumber(roadTransportCertificateNumber);
		vehicleInfo.setTrailerVehiclePlateNumber(tf.getTrailerVehiclePlateNumber());
		vehicleInfo.setOwner(tf.getOwner());
		vehicleInfo.setPermitNumber(tf.getCarPermitNumber());
		vehicleInfo.setDriver(driver);
		vehicleInfo.setGoodsInfo(goodsInfo);

		/** ============== 开始组装Body节点 ============== **/
		Body body = of.createRootBody();
		body.setOriginalDocumentNumber(tf.getOriginalDocumentNumber());
		body.setShippingNoteNumber(tf.getShippingNoteNumber());
		body.setCarrier(tf.getCarrier());
		body.setUnifiedSocialCreditIdentifier(tf.getUnifiedSocialCreditIdentifier());
		body.setPermitNumber(tf.getPermitNumber());
		body.setConsignmentDateTime(tf.getConsignmentDateTime());
		body.setBusinessTypeCode(tf.getBusinessTypeCode());
		body.setDespatchActualDateTime(tf.getDespatchActualDateTime());
		body.setGoodsReceiptDateTime(tf.getGoodsReceiptDateTime());
		body.setConsignorInfo(consignorInfo);
		body.setConsigneeInfo(consigneeInfo);
		body.setPriceInfo(priceInfo);
		body.setVehicleInfo(vehicleInfo);
		body.setFreeText("文本");

		/** ============== 开始组装Header节点 ============== **/
		Header header = of.createRootHeader();
		header.setMessageReferenceNumber(tf.getShippingNoteNumber());
		header.setDocumentName("无车承运人电子路单");
		header.setDocumentVersionNumber("2015WCCYR");
		header.setSenderCode(tf.getSenderCode());
		header.setRecipientCode(logink.getToaddress());
		header.setMessageSendingDateTime(AppUtils.getCurrentDateString("yyyyMMddHHmmss"));
		header.setMessageFunctionCode("9");

		/** ============== 开始组装Root节点 ============== **/
		Root root = of.createRoot();
		root.setHeader(header);
		root.setBody(body);
		return root;
	}
}
